package cn.bearspark.article.provider.dao.buffer;

import cn.bearspark.article.provider.dao.key.ArticleBufferKeyBuilder;
import cn.bearspark.article.provider.dao.mapper.ArticleBaseMapper;
import cn.bearspark.article.provider.dao.mapper.ArticleCategoryMapper;
import cn.bearspark.common.enumeration.VisibilityEnum;
import cn.bearspark.framework.redis.starter.buffer.list.RedisBaseListBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 专栏 id 的 list 数据结构的缓存器
 *
 * @author f
 */
@Component
public class ArticleIdListBuffer extends RedisBaseListBuffer<Long> {

    private final ArticleBaseMapper articleBaseMapper;
    private final ArticleCategoryMapper articleCategoryMapper;

    private final ArticleBufferKeyBuilder articleBufferKeyBuilder;

    public ArticleIdListBuffer(RedisTemplate<String, Object> redisTemplate,
                               ArticleBaseMapper articleBaseMapper,
                               ArticleCategoryMapper articleCategoryMapper,
                               ArticleBufferKeyBuilder articleBufferKeyBuilder) {
        super(redisTemplate);

        this.articleBaseMapper = articleBaseMapper;
        this.articleCategoryMapper = articleCategoryMapper;
        this.articleBufferKeyBuilder = articleBufferKeyBuilder;
    }

    /**
     * 分页查询指定用户的指定分类下的专栏 id
     *
     * @param pageNum      页数
     * @param pageSize     元素数
     * @param categoryId   指定的分类 id，如果为 null，则表示查询全部专栏
     * @param userId       执行查询操作的用户 id
     * @param listedUserId 被查询的用户 id
     * @return 指定用户的指定分类下的专栏 id 的集合
     */
    public List<Long> page(int pageNum, int pageSize, Long categoryId, long userId, long listedUserId) {
        int visCode = userId == listedUserId ?
                VisibilityEnum.PRIVATE.getCode() :
                VisibilityEnum.PUBLIC.getCode();
        int start = (pageNum - 1) * pageSize;
        int end = start + pageSize - 1;
        boolean hasNotCategoryId = categoryId == null;
        return super.range(
                hasNotCategoryId ?
                        articleBufferKeyBuilder.buildUserArticleIdListKey(listedUserId, visCode) :
                        articleBufferKeyBuilder.buildUserCategoryArticleIdListKey(listedUserId, categoryId, visCode),
                start, end, () -> hasNotCategoryId ?
                        articleBaseMapper.listUserArticleId(start, pageSize, listedUserId, visCode) :
                        articleCategoryMapper.listUserArticleIdByCategoryId(start, pageSize,
                                listedUserId, categoryId, visCode)
        );
    }

    /**
     * 清理 指定用户 的专栏 id 的缓存
     *
     * @param userId 指定的用户 id
     */
    public void cleanBatch(long userId) {
        super.cleanWithPattern(articleBufferKeyBuilder.buildUserArticleIdListKeyPattern(userId));
    }
}
